import { UNIT_BAJ_ATTR_CONFIG } from "../../config/UnitFieldConfig";
import {  AttrChangeEnum, UnitAttrStruct } from "../../types/L_Type";
import UnitX from "../../entity/UnitX";
import L_AttrControlUtil from "../../utils/L_AttrControlUtil";
import UnitFieldChangeExc from "../unit_field_change/UnitAttrChangeEx";
import { UnitBaseAttrConfig } from "../../config/UnitBaseAttrConfig";
import { I2IDCache } from "../../constant/IdCache";
import L_Run from "../../utils/L_Run";

/**  */
export default class UnitXManager{
 
   private static G_UNITX:Map<number,UnitX>=new Map();
 
 


 /**
  *  获取unitx 如果不存在利用基础config的配置对象创建一个 并且管理到容器中
  * @param u  单位象地址unit
  * @param extraInitAttr 初始化额外属性 为了高效初始化 没有可以不传
  * @param uname 单位自定义名称 多数时候为测试用可以忽略
  * @param aliasName 单位自定义名称 多数时候为测试用可以忽略
  * @returns 
  */
static getUnitxAutoInitNil(u:any,extraInitAttr?:UnitAttrStruct,aliasName?:string):UnitX{
    let uxArr:[boolean,UnitX]=this.getUnitxCheckNew(u,extraInitAttr,aliasName);
    if(uxArr[0]){
        this.G_UNITX.set(uxArr[1].handle,uxArr[1])
    }
    return uxArr[1]
}    

 /**
  *  直接获取unitx 如果不存在直接使用基础config的配置对象 
  * 不会创建并且管理unitx对象 懒得回收
  * @param u 单位对象地址unitx
  * @param extraInitAttr 初始化额外属性 为了高效初始化 没有可以不传
  * @param aliasName 单位自定义名称 多数时候为测试用可以忽略
  * @returns 
  */
static getUnitx(u:any,extraInitAttr?:UnitAttrStruct,aliasName?:string):UnitX{
    return this.getUnitxCheckNew(u,extraInitAttr,aliasName)[1]
}    


 /**
  * 直接获取unitx 如果不存在直接使用基础config的配置对象 
  * @param u 单位对象地址unitx
  * @param extraInitAttr 初始化额外属性 为了高效初始化 没有可以不传
  * @param uname 单位自定义名称 多数时候为测试用可以忽略
  * @returns [boolean,UnitX] [是否没有在全局管理池中的boolean,创建的UnitX对象]
  */
 private static getUnitxCheckNew(u:any,extraInitAttr?:UnitAttrStruct,aliasName?:string):[boolean,UnitX]{
    let handle:number= L_Run.GetHandleId_L(u,u)
    // console.log(">>>>>>>>handle:",handle)
    // console.log(">>>>>>>>ex attr:",extraInitAttr)
    //let unam:string=L_Run.GetUnitName_L(u,uname || "um测试单位")
    let ux=this.G_UNITX.get(handle)
    let isNew=false
    if ( ux==null ){
        //根据类型从配置表获取初始化的配置   TODO      A001->1093677105
        let configAttr=(UnitBaseAttrConfig as any)[I2IDCache(L_Run.GetUnitTypeId_L(u,1093677105))] || undefined
        //console.log("config->>>>>",configAttr)
        let fAttr:any=undefined
        if(extraInitAttr!=undefined){
            fAttr=L_AttrControlUtil.deepCloneAttrStruct(configAttr)
            L_AttrControlUtil.mergeField(fAttr || {},extraInitAttr,AttrChangeEnum.INCREASE)
        }
        
        ux=new UnitX(u,handle,aliasName || fAttr.name ,fAttr?.lvl || 1,fAttr);
        isNew=true
    }
    return [isNew,ux]
}  

/**注销单位绑定的unitx释放内存 */
static destoryUnitx(u:unit){
    let handle:number=GetHandleId(u)
    this.G_UNITX.delete(handle)
}



// static incrUnitField(u:unit,incFields:UnitAttrStruct,incType:AttrChangeEnum){
//     if(incFields==null) return
//     //单位unitx对象不存在就创建对象
//     let ux=this.getUnitxAutoInitNil(u)
//     let fix=(incType==AttrChangeEnum.INCREASE?1:-1)
//     //1.第一类 二进制属性+自定义基础属性
//     if(incFields.unitField!=undefined){
//         //先直接修改ux对象  合并属性
//         L_AttrControlUtil.mergeField(ux.b_attrs,incFields.unitField,incType);
//         //遍历改变的值 进行API调用
//         for(let k in incFields.unitField){
//             if(k==UNIT_BAJ_ATTR_CONFIG.hp.key || k==UNIT_BAJ_ATTR_CONFIG.mp.key ){
//                 //生命 魔法改变 直接改变值  不用同步ux对象
//                 //UnitFieldChangeExc.incUnitStatHpMp(u,k as keyof UnitStatHpMp,fix*(incFields.unitField as any)[k])    
//                 console.log("hp|mp属性改变:",k,",",fix*(incFields.unitField as any)[k])
//             }else if(UNIT_BAJ_ATTR_CONFIG.indexOfBinKey(k)){
//                 //其他二进制属性改变  直接使用ux合并后的数值作为最终值
//                 //UnitFieldChangeExc.setUnitStatB(u,k as keyof UnitStatB,(ux.b_attrs as any)[k])
//                 console.log("binnary属性改变:",k,",",fix*(incFields.unitField as any)[k])
//             }else{
//                 //TODO 非二进制属性改变  韧性，暴击等自定义属性
//             }
//         }
//     }
//     //2.第二类元素增强
//     if(incFields.dtEnh!=undefined){
//         L_AttrControlUtil.mergeField(ux.dt_enh,incFields.dtEnh,incType)
//     }
//     //3.第三类元素抗性
//     if(incFields.dtRes!=undefined){
//         L_AttrControlUtil.mergeField(ux.dt_res,incFields.dtRes,incType)
//     }

// }  



// //增加单位的单一属性
// //handle:单位句柄
// //field_m_type: 属性大分类 枚举UNIT_FIELD_M_TYPE.xx.key   (注意传key字符串)
// //unit_field_key: 属性key 枚举UNIT_FIELD 类型 注意必须传key 而不是table{}
// //v: 正数增加  负数减少
// static incrUnitFieldByHandle(u:unit,field_m_type_key:string,unit_field_key:string,v:number){
//     //单位unitx对象不存在就创建对象
//     let ux=this.getUnitxAutoInitNil(u)
//     this.incrUnitFieldWithUnitx(ux,field_m_type_key,unit_field_key,v)
// }    


// //增加单位的单一属性
// //field_m_type: 属性大分类 枚举 UNIT_FIELD_M_TYPE.xx.key  (注意传key字符串)
// //unitx:Unitx单位实例
// //unit_field_key 属性子项 UNIT_FIELD.xx.key  or  DMG_TYPE.xx.key    (注意传key字符串)
// //v: 正数增加  负数减少
// private static incrUnitFieldWithUnitx(unitx:UnitX,field_m_type_key:string,sub_field_key:string,v:number){
   
//     //print("改变单位属性:"..field_m_type_key..","..sub_field_key..":"..tostring(v))
//     //单位当前此属性的值  不存在默认为0
//     let curFieldVal=getTableVal(unitx,0,field_m_type_key,sub_field_key)
    
//     //改变属性后重新赋值
//     curFieldVal=curFieldVal+v
//     unitx[field_m_type_key][sub_field_key]=curFieldVal

//     //真正需要改变单位属性的项目 必须在 UNIT_FIELD_CONFIG枚举中有配置
//     if ((field_m_type_key==UNIT_FIELD_M_TYPE.field.key and UNIT_FIELD_CONFIG[sub_field_key]~=null) ){
//         setUnitStat(unitx,UNIT_FIELD_CONFIG[sub_field_key],curFieldVal,v)
//     }
// } 


// //通过属性table增加单位的多项属性
// //handle:单位句柄
// //fieldTable: 属性table  参考menu 单位全属性定义  从最外层开始传递  （UNIT_FIELD_M_TYPE）
// //fixInsc: 1增加  -1减少
// static incrUnitFieldWithTableByHandle(handle,fieldTable,fixInsc)
//     let ux=getUnitxById(handle)
//     incrUnitFieldWithTableByUnitx(ux,fieldTable,fixInsc)
// }


// //通过属性table增加单位的多项属性
// //unitx:Unitx单位实例
// //fieldTable: 属性table  参考menu 单位全属性定义  从最外层开始传递  （UNIT_FIELD_M_TYPE）
// //fixInsc: 1增加  -1减少
// static incrUnitFieldWithTableByUnitx(unitx,fieldTable,fixInsc)
//     //printTable("道具改变属性",fieldTable)
//     for i, v in pairs(UNIT_FIELD_M_TYPE) do
//         let mtfield=fieldTable[i]
//         if ( mtfield~=null and v.cunitf ){  //cunitf只执行改变影响单位属性变化的项
//             //printTable("道具改变属性",mtfield)
//             for fk,fv in pairs(mtfield) do
//                 incrUnitFieldWithUnitx(unitx,i,fk,fv*fixInsc)
//             }    
//         }
//     }    
// }

  
}  